package com.xjj.service.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.xjj.entity.*;
import com.xjj.service.dto.AdviceDto;
import com.xjj.service.dto.AdviceReadDto;
import com.xjj.service.dto.StudentReadDto;
import com.xjj.service.enumeration.PublishRange;
import com.xjj.service.exception.VertifyException;
import com.xjj.service.feign.KlassFeignClient;
import com.xjj.service.mapper.AdviceMapper;
import com.xjj.service.service.AdviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description 通知
 * @Author zhangjin
 * @Date 2022/10/20 9:59
 */
@Service
public class AdviceServiceImpl extends ServiceImpl<AdviceMapper, Advice> implements AdviceService {
    private static final String ADVICE_PREX="advice:";
    @Autowired
    private AdviceMapper adviceMapper;

    @Autowired
    private KlassFeignClient klassFeignClient;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public void add(Advice advice) {
        if (advice.getAdviceCategoryId()==null||advice.getContent()==null||advice.getTitle()==null){
            throw new VertifyException("参数错误");
        }else{
            // 删除指定前缀的缓存
            String key = ADVICE_PREX+"*"; // 在要删除的前缀后加上*
            Set<String> keysSet = redisTemplate.keys(key);
            redisTemplate.delete(keysSet);
            adviceMapper.insert(advice);
        }
    }

    @Override
    public void update(Advice advice){
        if (advice.getAdviceCategoryId()==null||advice.getContent()==null||advice.getTitle()==null){
            throw new VertifyException("参数错误");
        }else if (advice.getKlassId()==null){
            throw new VertifyException("请指定班级");
        }else{
            // 删除指定前缀的缓存
            String key = ADVICE_PREX+"*"; // 在要删除的前缀后加上*
            Set<String> keysSet = redisTemplate.keys(key);
            redisTemplate.delete(keysSet);
            adviceMapper.updateAdvice(advice);
        }
    }

    @Override
    public void delete(Integer id) {
        // 删除指定前缀的缓存
        String key = ADVICE_PREX+"*"; // 在要删除的前缀后加上*
        Set<String> keysSet = redisTemplate.keys(key);
        redisTemplate.delete(keysSet);
        adviceMapper.deleteById(id);
    }

    /**
     * 查询10条通知，按照时间降序排列
     * @return
     */
    @Override
    public List<Advice> selectByPage() {
        QueryWrapper queryWrapper = new QueryWrapper();
        Page<Advice> page = new Page<>(1,10);
        queryWrapper.orderByDesc("time");
        Page result = adviceMapper.selectPage(page, queryWrapper);
        return result.getRecords();
    }

    @Override
    public List<Advice> selectAll() {
        return adviceMapper.selectList(null);
    }

    /**
     * 多条件分页查询,存入redis缓存key 规则： all - 所有通知 manage -当前登录人发布的通知  page 页数
     * @param advice
     * @param pageBean
     * @return
     */
    @Override
    public PageBean<Advice> selectByPages(PageBean pageBean,Advice advice) {
        com.github.pagehelper.Page p = PageHelper.startPage(pageBean.getCurrPage(), pageBean.getPageSize());
        if (advice!=null){
            List<Advice> adviceList = adviceMapper.selectByPages(advice);
            pageBean.setCurrPageSize(adviceList.size());
            pageBean.setData(adviceList);
            pageBean.setTotalNums((int) p.getTotal());
            pageBean.setTotalPages((int) p.getTotal());
            return pageBean;
        }
        // 存入redis中的key
        String key;
        // 存入redis的value
        Object cache;
        if (advice.getPublisherId()==null){
            // key拼接，所有的通知
            key= ADVICE_PREX + "all:"+"page"+pageBean.getCurrPage();
            cache = redisTemplate.opsForValue().get(key);
        }else{
            // 知识当前登录人的通知
            key = ADVICE_PREX + "publisher:"+"managerId:"+advice.getPublisherId()+":page"+pageBean.getCurrPage();
            cache = redisTemplate.opsForValue().get(key);
        }
        // 判断缓存是否存在，存在直接返回
        if (cache!=null){
            return (PageBean<Advice>) cache;
        }else {
            List<Advice> adviceList = adviceMapper.selectByPages(advice);
            pageBean.setCurrPageSize(adviceList.size());
            pageBean.setData(adviceList);
            pageBean.setTotalNums((int) p.getTotal());
            pageBean.setTotalPages((int) p.getTotal());
            redisTemplate.opsForValue().set(key,pageBean);
            return pageBean;
        }
    }

    @Override
    public AdviceDto getAdviceById(Integer id) {
        AdviceDto adviceDto = adviceMapper.getAdviceById(id);
        return adviceDto;
    }

    @Override
    public Integer getAdviceReadNum(Integer id) {
        Advice advice = adviceMapper.selectById(id);
        int num = 0;
        if ("全校".equals(advice.getPubRange())){
            List<AdviceReadDto> studentReadDto = adviceMapper.getStudentReadDto(id);
            for (AdviceReadDto dto : studentReadDto) {
                num +=dto.getReadNum();
            }
        }else{
            AdviceReadDto dto = adviceMapper.getStudentReadDtoOneClass(id, advice.getKlassId());
            num = dto.getReadNum();
        }
        return num;
    }

    @Override
    public List<AdviceReadDto> getClassReadNum(Integer id) {
        Advice advice = adviceMapper.selectById(id);
        List<AdviceReadDto> studentReadDto = new ArrayList<>();
        if (advice.getKlassId()==null) {
            studentReadDto = adviceMapper.getStudentReadDto(id);
            // 获取class id集合
            List<Integer> classIdList = new ArrayList();
            for (AdviceReadDto adviceReadDto : studentReadDto) {
                classIdList.add(adviceReadDto.getClassId());
            }
            // 获取所有的班级
            ResponseEntity result = klassFeignClient.findAllKlass();
            List<Klass> klassList = JSONArray.parseArray(JSONObject.toJSONString(result.getData()), Klass.class);
            // 筛选出没有在表中的数据
            List<Klass> classList1 = klassList.stream().filter(r -> !classIdList.contains(r.getId())).collect(Collectors.toList());
            for (Klass klass : classList1) {
                AdviceReadDto dto = new AdviceReadDto(klass.getId(),klass.getName(),0,klass.getKlassNum());
                studentReadDto.add(dto);
            }
        }else{
            AdviceReadDto dto = adviceMapper.getStudentReadDtoOneClass(id, advice.getKlassId());
            studentReadDto.add(dto);
        }
        for (AdviceReadDto dto : studentReadDto) {
            ResponseEntity result = klassFeignClient.getKlassById(dto.getClassId());
            Map map = (Map) result.getData();
            dto.setUnreadNum((Integer) map.get("klassNum")-dto.getReadNum());
        }
        return studentReadDto;
    }

    @Override
    public PageBean<StudentReadDto> getStuReadAdvice(PageBean pageBean, Advice advice) {
        // 查询已读的学生列表
        List<StudentReadDto> readStu = adviceMapper.getReadStu(advice.getId());
        // 获取一个班级下的所有学生,分页查询
        com.github.pagehelper.Page p = PageHelper.startPage(pageBean.getCurrPage(), pageBean.getPageSize());
        List<StudentReadDto> readStuList = adviceMapper.getReadStuList(advice.getKlassId());
        for (StudentReadDto studentReadDto : readStuList) {
            if (readStu.contains(studentReadDto)){
                studentReadDto.setFlag(0);
            }else{
                studentReadDto.setFlag(1);
            }
        }
        pageBean.setCurrPageSize(readStuList.size());
        pageBean.setData(readStuList);
        pageBean.setTotalNums((int) p.getTotal());
        pageBean.setTotalPages((int) p.getTotal());
        return pageBean;
    }

    /**
     * 查询全校通知
     * @return
     */
    @Override
    public List<Advice> getParentAdvice() {
        String value = PublishRange.getValue(String.valueOf(1));
        List<Advice> parentAdvice = adviceMapper.getParentAdvice(value);
        // 处理时间，如果年份与今年相同，则显示月份日期，否则，显示年月日
        for (Advice advice : parentAdvice) {
            try {
                advice.setTime(util.GetCurrentTime.timeConversion(advice.getTime()));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return parentAdvice;
    }

    /**
     * 根据家长id查询学生班级的所有通知
     * @param pid
     * @return
     */
    @Override
    public List<Advice> getClassAdvice(Integer pid) {
        List<Advice> adviceList = adviceMapper.getClassAdvice(pid);
        for (Advice advice : adviceList) {
            try {
                advice.setTime(util.GetCurrentTime.timeConversion(advice.getTime()));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return adviceList;
    }


}
